home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / comm / bbs / cit_src_7H21.lha / callstat.c < prev    next >
C/C++ Source or Header  |  1997-08-03  |  20KB  |  760 lines

  1.  
  2. /*
  3. Hue: This is the source of the current version of callstat.  I've been
  4. running it on my system for some time, and it seems to be stable.
  5. Unfortunately, one of the other Swarm Sysops, who has a hard-drive-
  6. based STadel node, has reported that this version of callstat acts
  7. very strangely with his system.  I haven't yet figured where the
  8. problem is...
  9. In any case, the basic logic is sound, and fairly straightforward.
  10. The program is undocumented as yet; I haven't reached the point
  11. where I'm ready to release it to the public, and I never document
  12. my own code...until it's too late.  :-)  Anyway, I don't expect
  13. you'll have much trouble figuring things out.  The only problem
  14. areas are in the Cit-specific stuff, such as access to ctdltabl.sys
  15. and calllog.sys.
  16. Any comments, questions, complaints, or speeches would be welcomed,
  17. unless they deal with my personal programming style.  :-)
  18. --Royce, 13Mar88, far too late in the evening...
  19. */
  20. #define BOOLEAN int
  21. #define CITADEL86       1
  22. /* #define ATARI_ST        1 */
  23. #include "ctdl.h"    /* header file  */
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <math.h>
  28. #include <ctype.h>
  29. #include <time.h>
  30. #include <proto/exec.h>
  31. #include <dos/dos.h>
  32. #include <pragmas/dos_pragmas.h>
  33. #include "exec/memory.h"
  34. #include "exec/ports.h"
  35. #include "exec/exec.h"
  36. #ifdef ATARI_ST
  37. #include <osbind.h>
  38. #include "audit.h"
  39. extern struct config    cfg;
  40. #endif
  41. #ifdef CITADEL86
  42. #define safeopen        fopen
  43. #define Cconin()        getchar()
  44. #define Fdelete         unlink
  45. #define doExit          exit
  46. typedef char pathSpec[200];
  47. extern CONFIG           cfg;
  48. void get_data(void);
  49. void munch(void);
  50. void write_data(void);
  51. void write_stat_file(void);
  52. void UpdateBar(void);
  53. long baud_code(long baud);
  54. void file_error(char *file, char *access);
  55. BOOLEAN find_on(void);
  56. char get_stuff(void);
  57. void write_a_stat(char *desc, char stat);
  58. void write_hist_bar(unsigned stat, float factor);
  59. #endif
  60. struct
  61.   {
  62.   unsigned hour,min;
  63.  
  64.   }
  65. on,off,last;
  66. BOOLEAN newuser,termstay,disconnect,preempt,timeout,evile,nosysop,update,docb,
  67. debug, barupdate, SysUp = FALSE;
  68. char    ch,date[20],str[20];
  69. long baud;
  70. unsigned long dur;
  71. FILE    *safeopen(),*fp;
  72. pathSpec fnlog = "",fndat,fnstat,fncallbaud;
  73. long total,calls[24],durations[20],callbaud[24][9],
  74. nnewusers,ntermstays,ndisconnects,nnewdiscons,npreempts,
  75. ntimeouts,neviles;
  76. long bauds[9] =
  77.   {
  78.   0, 0, 0,  0, 0, 0,  0, 0, 0
  79.  
  80.   };
  81. long    totalduration,totalidle, netcount;
  82. long    baudduration[9] =
  83.   {
  84.   0l, 0l, 0l,  0l, 0l, 0l,  0l, 0l, 0l
  85.  
  86.   };
  87. char    bartitle[100] = "";
  88. int main(int , char **);
  89. int main(argc,argv)
  90. int     argc;
  91. char    *argv[];
  92.   {
  93.   cfg.weAre = UTILITY;
  94.   printf("Citadel Caller Log Statistics Report, %s\n", VERSION_NAME);
  95.   printf("Do a 'callstat -?' for help.\n");
  96.   nosysop = FALSE;
  97.   update = FALSE;
  98.   docb = FALSE;
  99.   debug = FALSE;
  100.   while (argc > 1)
  101.     {
  102.     --argc;
  103.     ++argv;
  104.     #ifndef CITADEL86
  105.     if (strcmp(*argv, "-c") == 0)
  106.     docb = TRUE;
  107.     if (strcmp(*argv, "-d") == 0)
  108.     debug = TRUE;
  109.     if (strcmp(*argv, "-s") == 0)
  110.     nosysop = TRUE;
  111.     if (strcmp(*argv, "-u") == 0)
  112.     update = TRUE;
  113.     if (strcmp(*argv, "-?") == 0)
  114.       {
  115.       printf("usage: callstat [-c] [-s] [-u]\n");
  116.       printf("       -c writes callbaud.sys\n");
  117.       printf("       -s turns off sysConsole stats\n");
  118.       printf("       -u deletes calllog.sys & updates calldata.sys\n");
  119.       doExit(0);
  120.  
  121.       }
  122.     #else
  123.     if (strcmp(*argv, "-c") == 0)
  124.     docb = TRUE;
  125.     else if (strcmp(*argv, "-d") == 0)
  126.     debug = TRUE;
  127.     else if (strcmp(*argv, "-s") == 0)
  128.     nosysop = TRUE;
  129.     else if (strcmp(*argv, "-u") == 0)
  130.     update = TRUE;
  131.     else if (strncmp(*argv, "-b", 2) == 0)
  132.       {
  133.       barupdate = TRUE;
  134.       if (strlen(*argv) > 2)
  135.       strcpy(bartitle, *argv + 2);
  136.  
  137.       }
  138.     else if (strcmp(*argv, "-?") == 0)
  139.       {
  140.       printf("usage: callstat [-c] [-s] [-u] [filename]\n");
  141.       printf("       -c writes callbaud.sys\n");
  142.       printf("       -s turns off sysConsole stats\n");
  143.       printf("       -u deletes calllog.sys & updates calldata.sys\n");
  144.       printf("       -b[title name] updates bar.sys\n");
  145.       printf("       \"filename\" analyze this file, instead\n");
  146.       doExit(0);
  147.  
  148.       }
  149.     else if (**argv != '-')
  150.       {
  151.       strcpy(fnlog, *argv);
  152.  
  153.       }
  154.     #endif
  155.  
  156.     }
  157.   #ifdef ATARI_ST
  158.   if (!readSysTab(FALSE))
  159.   #endif
  160.   #ifdef CITADEL86
  161.   if (!readSysTab(FALSE, TRUE))
  162.   #endif
  163.   doExit(1);
  164.   #ifdef ATARI_ST
  165.   if (((cfg.call_log & aEXIT) == 0) || ((cfg.call_log & aLOGIN) == 0) ||
  166.   ((cfg.call_log & aDNLOAD == 1)))
  167.     {
  168.     printf("Sorry, but callstat currently needs system ups & downs\n");
  169.     printf("and user logins to be recorded, and file transfers to\n");
  170.     printf("be unrecorded.\n");
  171.     doExit(1);
  172.  
  173.     }
  174.   #endif
  175.   #ifdef ATARI_ST
  176.   if (strlen(fnlog) == 0)
  177.   sprintf(fnlog,"%s\\CALLLOG.SYS",&cfg.codeBuf[cfg.auditDir]);
  178.   sprintf(fndat,"%s\\CALLDATA.SYS",&cfg.codeBuf[cfg.sysDir]);
  179.   sprintf(fnstat,"%s\\CALLSTAT.SYS",&cfg.codeBuf[cfg.auditDir]);
  180.   sprintf(fncallbaud,"%s\\CALLBAUD.SYS",&cfg.codeBuf[cfg.auditDir]);
  181.   #endif
  182.   #ifdef CITADEL86
  183.   if (strlen(fnlog) == 0)
  184.   makeSysName(fnlog, "calllog.sys", &cfg.auditArea);
  185.   makeSysName(fndat, "calldata.sys", &cfg.auditArea);
  186.   makeSysName(fnstat, "callstat.sys", &cfg.auditArea);
  187.   makeSysName(fncallbaud, "callbaud.sys", &cfg.auditArea);
  188.   #endif
  189.   last.hour = 100;
  190.   get_data();
  191.   munch();
  192.   if (update)
  193.     {
  194.     Fdelete(fnlog);
  195.     write_data();
  196.  
  197.     }
  198.   #ifdef CITADEL86
  199.   if (barupdate)
  200.     {
  201.     UpdateBar();
  202.  
  203.     }
  204.   #endif
  205.   write_stat_file();
  206.   return 0;
  207.  
  208.   }
  209. void file_error(char *file, char *access)
  210.   {
  211.   printf("Can't open %s for %s!\n",file,access);
  212.   printf("Hit return: "); /* For people running under GEM desktop. */
  213.   ch = Cconin();
  214.   printf("\n");
  215.  
  216.   }
  217. void get_data()
  218.   {
  219.   unsigned        i,j;
  220.   if ((fp = safeopen(fndat,"r")) == NULL)
  221.     {
  222.     date[0] = NULL;
  223.     total = 0;
  224.     zero_struct(calls);
  225.     zero_struct(durations);
  226.     totalduration = 0;
  227.     totalidle = 0;
  228.     zero_struct(bauds);
  229.     zero_struct(callbaud);
  230.     nnewusers = 0;
  231.     ntermstays = 0;
  232.     ndisconnects = 0;
  233.     nnewdiscons = 0;
  234.     npreempts = 0;
  235.     ntimeouts = 0;
  236.     neviles = 0;
  237.  
  238.     }
  239.   else
  240.     {
  241.     printf("Reading cumulative data...\n");
  242.     fscanf(fp,"%s\n",date);
  243.     fscanf(fp,"%d\n",&total);
  244.     for (i = 0; i <= 23; i++)
  245.     fscanf(fp,"%d\n",&calls[i]);
  246.     for (i = 0; i <= 19; i++)
  247.     fscanf(fp,"%d\n",&durations[i]);
  248.     fscanf(fp,"%ld\n",&totalduration);
  249.     fscanf(fp,"%ld\n",&totalidle);
  250.     for (i = 0; i <= 8; i++)
  251.     fscanf(fp,"%d\n",&bauds[i]);
  252.     for (i = 0; i <= 23; i++)
  253.     for (j = 0; j <= 8; j++)
  254.     fscanf(fp,"%d\n",&callbaud[i][j]);
  255.     fscanf(fp,"%d\n",&nnewusers);
  256.     fscanf(fp,"%d\n",&ntermstays);
  257.     fscanf(fp,"%d\n",&ndisconnects);
  258.     fscanf(fp,"%d\n",&nnewdiscons);
  259.     fscanf(fp,"%d\n",&npreempts);
  260.     fscanf(fp,"%d\n",&ntimeouts);
  261.     fscanf(fp,"%d\n",&neviles);
  262.     fclose(fp);
  263.  
  264.     }
  265.  
  266.   }
  267. long baud_code(long baud)
  268.   {
  269.   if (baud == 300)            return 1;
  270.   else if (baud == 1200)      return 2;
  271.   else if (baud == 2400)      return 3;
  272.   else if (baud == 4800)      return 4;
  273.   else if (baud == 9600)      return 5;
  274.   else if (baud == 14400)     return 6;
  275.   else if (baud == 19200)     return 7;
  276.   else if (baud >= 38400)     return 8;
  277.   else  return 0;
  278.  
  279.   }
  280. char isnet;
  281. BOOLEAN find_on()       /* Scan for next user login time. */
  282.   {
  283.   int     rc;
  284.   char    up, buffer[800];
  285.   buffer[0] = 0;
  286.   do
  287.     {
  288.     str[0] = NULL;
  289.     rc = fscanf(fp,"%s ",str);
  290.     if (debug)                     printf("-%s-",str);
  291.     if (strcmp(str, "up") == 0)    up = TRUE;
  292.     /* Next if handles system down/up. */
  293.     if( strlen(str) + strlen(buffer) > sizeof(buffer) )
  294.       {
  295.       printf("Possible corruption in calllog.sys at --%s--\n", str);
  296.       buffer[0] = 0;
  297.       };
  298.     strcat(buffer, str);
  299.     if ((rc == 1) && (str[0] == '@'))
  300.       {
  301.       if (debug)
  302.       printf("\n");
  303.       if (last.hour != 100)
  304.         {
  305.         if (SysUp && up)
  306.           {
  307.           /* damaged calllog */
  308.           fscanf(fp,"%d:",&last.hour);
  309.           fscanf(fp,"%d\n",&last.min);
  310.           on.hour = 100;
  311.  
  312.           }
  313.         else
  314.           {
  315.           fscanf(fp,"%d:",&on.hour);
  316.           fscanf(fp,"%d\n",&on.min);
  317.  
  318.           }
  319.  
  320.         }
  321.       else
  322.         {
  323.         fscanf(fp,"%d:",&last.hour);
  324.         fscanf(fp,"%d\n",&last.min);
  325.         on.hour = 100;
  326.  
  327.         }
  328.       if (on.hour != 100)
  329.         {
  330.         if (last.hour > on.hour)
  331.         on.hour += 24;
  332.         dur = ((on.hour * 60 + on.min) - (last.hour * 60 + last.min));
  333.         /*printf("\n1: adding %d\n", dur);*/
  334.         totalidle += dur;
  335.         last.hour = 100;
  336.  
  337.         }
  338.       up = FALSE;
  339.  
  340.       }
  341.  
  342.     }
  343.   while (strcmp(str, "mode:")
  344.     && (rc != EOF) && ((str[0] != ':') || (str[1] != NULL)));
  345.   if (debug)  printf("buffer is -%s-", buffer);
  346.   /*
  347.   Bug: Normally, the only time the substring " : " shows up in the
  348.   calllog, is between a userID and the date of the login.  Thus
  349.   the previous while loop scans for words (i.e. a sequence of
  350.   characters terminated by white-space), and terminates when it
  351.   finds the word ": ".  Normally, this means that the date and
  352.   time of signon are to immediately follow.
  353.   However, if some userID contains the substring " : " (or ": "
  354.   at the start), callstat will rapidly go to heg.  More
  355.   stringent error-checking is needed to guard against this
  356.   (e.g., check to make sure that something of the form ddCccdd
  357.   follows the current instance of ": ", where d is a digit and
  358.   C/c is a character)...
  359.   */
  360.   if (debug)  printf("\n");
  361.   if (rc == EOF)
  362.     return FALSE;
  363.   else
  364.     {
  365.     SysUp = TRUE;
  366.     fscanf(fp,"%s ",str);   /* Skip the date */
  367.     if (date[0] == NULL)    /* Record it if needed (first time) */
  368.     strcpy(date,str);
  369.     isnet = (strcmp(buffer, "Systeminnetworkmode:") == 0);
  370.     return TRUE;
  371.  
  372.     }
  373.  
  374.   }
  375. char get_stuff()
  376.   {
  377.   int     rc;
  378.   fscanf(fp,"%d:",&on.hour);
  379.   fscanf(fp,"%d - ",&on.min);
  380.   rc = fscanf(fp,"%d:",&off.hour);
  381.   if (rc != 1)
  382.     {
  383.     printf("\nYuck!  Your calllog.sys file is corrupted!\n");
  384.     printf("(A user is recorded as logging in, but not out.)\n");
  385.     printf("Please use an editor to fix things before rerunning.\n");
  386.     fclose(fp);
  387.     doExit(1);
  388.  
  389.     }
  390.   fscanf(fp, (isnet) ? "%d" : "%d (", &off.min);
  391.   if (!isnet)
  392.     {
  393.     rc = fscanf(fp,"%d)",&baud);
  394.     if (rc == 0)
  395.       {
  396.       /* Login was at sysConsole */
  397.       baud = 0;
  398.       fscanf(fp,"%s)",str);
  399.  
  400.       }
  401.     baud = baud_code(baud);
  402.  
  403.     }
  404.   else baud = 0;
  405.   newuser = FALSE;
  406.   termstay = FALSE;
  407.   disconnect = FALSE;
  408.   preempt = FALSE;
  409.   timeout = FALSE;
  410.   evile = FALSE;
  411.   do
  412.     {
  413.     ch = getc(fp);
  414.     switch (ch)
  415.       {
  416.       case '+' :
  417.       newuser = TRUE;
  418.       break;
  419.       case '-' :
  420.       termstay = TRUE;
  421.       break;
  422.       case 'd' :
  423.       disconnect = TRUE;
  424.       break;
  425.       case 'p' :
  426.       preempt = TRUE;
  427.       break;
  428.       case 't' :
  429.       timeout = TRUE;
  430.       break;
  431.       case 'E' :
  432.       evile = TRUE;
  433.       default :
  434.       break;
  435.  
  436.       }
  437.  
  438.     }
  439.   while (ch != '\n');
  440.   return isnet;
  441.  
  442.   }
  443. void munch()
  444.   {
  445.   char net;
  446.   if ((fp = safeopen(fnlog,"r")) == NULL)
  447.     {
  448.     file_error("calllog.sys","input");
  449.     return;
  450.  
  451.     }
  452.   printf("Munching...\n");
  453.   while (find_on())
  454.     {
  455.     net = get_stuff();
  456.     if (!net) total++;
  457.     printf("\r%d",total);
  458.     if (!net) calls[on.hour]++;
  459.     if (last.hour > on.hour)
  460.     on.hour += 24;
  461.     dur=((on.hour*60+on.min)-(last.hour*60+last.min));
  462.     /*printf("\n2: adding %ld (Last was %d:%02d, now is %d:%02d)\n", dur, last.hour, last.min, on.hour, on.min);*/
  463.     totalidle += dur;
  464.     if (on.hour >= 24)
  465.     on.hour -= 24;
  466.     last.hour = off.hour;
  467.     last.min = off.min;
  468.     if (on.hour > off.hour)
  469.     off.hour += 24;
  470.     dur=((off.hour*60+off.min) - (on.hour * 60 + on.min));
  471.     if (!net)
  472.       {
  473.       totalduration += dur;
  474.       baudduration[baud] += dur;
  475.  
  476.       }
  477.     else netcount++;
  478.     dur /= 15;
  479.     if (dur > 19)
  480.     dur = 19;
  481.     if (!net)
  482.       {
  483.       durations[dur]++;
  484.       bauds[baud]++;
  485.       callbaud[on.hour][baud]++;
  486.       if (newuser)
  487.       nnewusers++;
  488.       if (termstay)
  489.       ntermstays++;
  490.       if (disconnect)
  491.         {
  492.         ndisconnects++;
  493.         if (newuser)
  494.         nnewdiscons++;
  495.  
  496.         }
  497.       if (preempt)
  498.       npreempts++;
  499.       if (timeout)
  500.       ntimeouts++;
  501.       if (evile)
  502.       neviles++;
  503.  
  504.       }
  505.  
  506.     }
  507.   fclose(fp);
  508.   printf("\n");
  509.  
  510.   }
  511. void write_data()
  512.   {
  513.   unsigned        i,j;
  514.   if ((fp = safeopen(fndat,"w")) == NULL)
  515.   file_error("calldata.sys","output");
  516.   else
  517.     {
  518.     printf("Writing cumulative data...\n");
  519.     fprintf(fp,"%s\n",date);
  520.     fprintf(fp,"%d\n",total);
  521.     for (i = 0; i <= 23; i++)
  522.     fprintf(fp,"%d\n",calls[i]);
  523.     for (i = 0; i <= 19; i++)
  524.     fprintf(fp,"%d\n",durations[i]);
  525.     fprintf(fp,"%ld\n",totalduration);
  526.     fprintf(fp,"%ld\n",totalidle);
  527.     for (i = 0; i <= 8; i++)
  528.     fprintf(fp,"%d\n",bauds[i]);
  529.     for (i = 0; i <= 23; i++)
  530.     for (j = 0; j <= 8; j++)
  531.     fprintf(fp,"%d\n",callbaud[i][j]);
  532.     fprintf(fp,"%d\n",nnewusers);
  533.     fprintf(fp,"%d\n",ntermstays);
  534.     fprintf(fp,"%d\n",ndisconnects);
  535.     fprintf(fp,"%d\n",nnewdiscons);
  536.     fprintf(fp,"%d\n",npreempts);
  537.     fprintf(fp,"%d\n",ntimeouts);
  538.     fprintf(fp,"%d\n",neviles);
  539.     fclose(fp);
  540.  
  541.     }
  542.  
  543.   }
  544. void write_hist_bar(unsigned stat, float factor)
  545.   {
  546.   unsigned        i;
  547.   fprintf(fp,": ");
  548.   if ((stat / factor) >= 1.0)
  549.   for (i = 1; i <= (int) (stat / factor); i++)
  550.   fprintf(fp,"*");
  551.   else if (stat >= 1)
  552.   fprintf(fp,"*");
  553.   fprintf(fp," (%d)\n", stat);
  554.   fflush(fp);
  555.  
  556.   }
  557. void write_a_stat(char *desc, char stat)
  558.   {
  559.   #ifndef CITADEL86
  560.   fprintf(fp,"%s: %d (%d%%)\n",desc,stat,stat * 100 / total);
  561.   #else
  562.   fprintf(fp, "%-30s%-15d%d\n", desc, stat, stat * 100 / total);
  563.   #endif
  564.  
  565.   }
  566. void write_stat_file()
  567.   {
  568.   unsigned        i,j,max;
  569.   float           factor;
  570.   Fdelete(fnstat);
  571.   if ((fp = safeopen(fnstat,"w")) == NULL)
  572.   file_error("callstat.sys","output");
  573.   else
  574.     {
  575.     printf("Writing stat file...\n");
  576.     fprintf(fp,"\n The Antithesystem Memorial RT Histogram.\n\n");
  577.     fprintf(fp," The following statistics have been collected since %s.\n\n",date);
  578.     fprintf(fp," Total number of calls represented: %d\n\n",total);
  579.     max = 25;
  580.     for (i = 0; i <= 23; i++)
  581.     if (calls[i] > max)
  582.     max = calls[i];
  583.     factor = max / 25.0;
  584.     fprintf(fp," Usage histogram (each number represents an hour of the day, each '*'\n");
  585.     fprintf(fp,"represents about %d calls at that hour):\n",(int) factor);
  586.     for (i = 0; i <= 23; i++)
  587.       {
  588.       fprintf(fp,"%3d",i);
  589.       write_hist_bar(calls[i],factor);
  590.  
  591.       }
  592.     fprintf(fp,"\n");
  593.     max = 25;
  594.     for (i = 0; i <= 19; i++)
  595.     if (durations[i] > max)
  596.     max = durations[i];
  597.     factor = max / 25.0;
  598.     fprintf(fp," Call duration histogram (each number represents a call duration of at\n");
  599.     fprintf(fp,"most that much time, each '*' represents about %d calls of that duration):\n",(int) factor);
  600.     for (i = 0; i <= 19; i++)
  601.       {
  602.       fprintf(fp,"%2d:%d",(i + 1) * 15 / 60,(i + 1) * 15 % 60);
  603.       if (i % 4 == 3)
  604.       fprintf(fp,"0");
  605.       write_hist_bar(durations[i],factor);
  606.  
  607.       }
  608.     fprintf(fp," The average call duration is about %ld minutes.\n",totalduration / total);
  609.     fprintf(fp," The average idle time before/after a call is about %ld minutes.\n\n",totalidle / total);
  610.     max = 25;
  611.     for (i = 0; i <= 8; i++)
  612.     if (bauds[i] > max)
  613.     max = bauds[i];
  614.     factor = max / 25.0;
  615.     fprintf(fp," Baud rate histogram (each number represents a baud rate, each '*' represents\n");
  616.     fprintf(fp,"about %d calls at that baud rate):\n",(int) factor);
  617.     for (i = 0 + nosysop; i <= cfg.sysBaud + 1; i++)
  618.       {
  619.       switch (i)
  620.         {
  621.         case 0 :  fprintf(fp,"  sys");  break;
  622.         case 1 :  fprintf(fp,"  300");  break;
  623.         case 2 :  fprintf(fp," 1200");  break;
  624.         case 3 :  fprintf(fp," 2400");  break;
  625.         case 4 :  fprintf(fp," 4800");  break;
  626.         case 5 :  fprintf(fp," 9600");  break;
  627.         case 6 :  fprintf(fp,"14400");  break;
  628.         case 7 :  fprintf(fp,"19200");  break;
  629.         case 8 :  fprintf(fp,"38400");  break;
  630.  
  631.         }
  632.       write_hist_bar(bauds[i],factor);
  633.  
  634.       }
  635.     fprintf(fp,"\n");
  636.     fprintf(fp, "There were %ld network sessions.\n\n", netcount);
  637.     #ifndef CITADEL86
  638.     write_a_stat(" Number of new users",nnewusers);
  639.     write_a_stat(" Number of uses of .T(erminate) S(tay)",ntermstays);
  640.     write_a_stat(" Number of disconnects",ndisconnects);
  641.     write_a_stat(" Number of new user disconnects",nnewdiscons);
  642.     write_a_stat(" Number of preemptions",npreempts);
  643.     write_a_stat(" Number of time-outs",ntimeouts);
  644.     write_a_stat(" Number of EVILE users",neviles);
  645.     #else
  646.     fprintf(fp, "%-25s%-15s%s\n", " Description",
  647.     "Total Number", "Percentage");
  648.     fprintf(fp, "%-25s%-15s%s\n", " -----------",
  649.     "------------", "----------");
  650.     write_a_stat(" New users", nnewusers);
  651.     write_a_stat(" .T(erminate) S(tay) usage", ntermstays);
  652.     write_a_stat(" Disconnects", ndisconnects);
  653.     write_a_stat(" New user disconnects", nnewdiscons);
  654.     write_a_stat(" Preemptions", npreempts);
  655.     write_a_stat(" Time-outs", ntimeouts);
  656.     write_a_stat(" EVILE users", neviles);
  657.     #endif
  658.     fclose(fp);
  659.  
  660.     }
  661.   if (docb != TRUE)
  662.   return;
  663.   Fdelete(fncallbaud);
  664.   if ((fp = safeopen(fncallbaud,"w")) == NULL)
  665.   file_error("callbaud.sys","output");
  666.   else
  667.     {
  668.     printf("Writing call/baud file...\n");
  669.     fprintf(fp,"\n");
  670.     fprintf(fp," The following statistics have been collected since %s.\n\n",date);
  671.     fprintf(fp," Total number of calls represented: %d\n\n",total);
  672.     max = 25;
  673.     for (i = 0; i <= 23; i++)
  674.     for (j = 0; j <= 8; j++)
  675.     if (callbaud[i][j] > max)
  676.     max = callbaud[i][j];
  677.     factor = max / 25.0;
  678.     fprintf(fp," Usage/baud rate histogram (each pair of numbers represents an hour of the\n");
  679.     fprintf(fp,"day and a baud rate, each '*' represents about %d calls at that hour and\n",(int) factor);
  680.     fprintf(fp,"baud rate):\n");
  681.     for (i = 0; i <= 23; i++)
  682.     for (j = 0 + nosysop; j <= cfg.sysBaud + 1; j++)
  683.       {
  684.       fprintf(fp,"%3d,",i);
  685.       switch (j)
  686.         {
  687.         case 0 :  fprintf(fp,"  sys");  break;
  688.         case 1 :  fprintf(fp,"  300");  break;
  689.         case 2 :  fprintf(fp," 1200");  break;
  690.         case 3 :  fprintf(fp," 2400");  break;
  691.         case 4 :  fprintf(fp," 4800");  break;
  692.         case 5 :  fprintf(fp," 9600");  break;
  693.         case 6 :  fprintf(fp,"14400");  break;
  694.         case 7 :  fprintf(fp,"19200");  break;
  695.         case 8 :  fprintf(fp,"38400");  break;
  696.  
  697.         }
  698.       write_hist_bar(callbaud[i][j],factor);
  699.  
  700.       }
  701.     fclose(fp);
  702.  
  703.     }
  704.  
  705.   }
  706. void crashout(str)
  707. char *str;
  708.   {
  709.   puts(str);
  710.   doExit(1);
  711.  
  712.   }
  713. /*
  714. * Note Royce doesn't support 4800, so we must force in a 0.
  715. */
  716. void UpdateBar()
  717.   {
  718.   FILE *fd, *fopen();
  719.   extern char *APPEND_TEXT;
  720.   if ((fd = fopen("bar.sys", APPEND_TEXT)) != NULL)
  721.     {
  722.     if (strlen(bartitle) == 0)
  723.       {
  724.       printf("Title for this data: ");
  725.       gets(bartitle);
  726.  
  727.       }
  728.     fprintf(fd, "%s\n", bartitle);
  729.     fprintf(fd, "%d\n", bauds[0]);
  730.     fprintf(fd, "%ld\n", baudduration[0]);
  731.     fprintf(fd, "%d\n", bauds[1]);
  732.     fprintf(fd, "%ld\n", baudduration[1]);
  733.     fprintf(fd, "%d\n", bauds[2]);
  734.     fprintf(fd, "%ld\n", baudduration[2]);
  735.     fprintf(fd, "%d\n", bauds[3]);
  736.     fprintf(fd, "%ld\n", baudduration[3]);
  737.     fprintf(fd, "%d\n", bauds[4]);
  738.     fprintf(fd, "%ld\n", baudduration[4]);
  739.     fprintf(fd, "%d\n", bauds[5]);
  740.     fprintf(fd, "%ld\n", baudduration[5]);
  741.     fprintf(fd, "%d\n", bauds[6]);
  742.     fprintf(fd, "%ld\n", baudduration[6]);
  743.     fprintf(fd, "%d\n", bauds[7]);
  744.     fprintf(fd, "%ld\n", baudduration[7]);
  745.     fprintf(fd, "%d\n", bauds[8]);
  746.     fprintf(fd, "%ld\n", baudduration[8]);
  747.     fprintf(fd, "%d\n", 0);
  748.     fprintf(fd, "0\n");
  749.     fprintf(fd, "%d\n", bauds[8]);
  750.     fprintf(fd, "%ld\n", baudduration[8]);
  751.     fprintf(fd, "%ld\n", totalduration);
  752.     fprintf(fd, "%ld\n", totalidle);
  753.     fprintf(fd, "%d\n", nnewusers);
  754.     fprintf(fd, "\n");
  755.     fclose(fd);
  756.  
  757.     }
  758.  
  759.   }
  760.